/*
 * LDIR
 * 
 * LDIR, a GPS cartography application built for Let's Do It Romania eco 
 * campaign.
 * Copyright (C) 2010 Genera Software <office@generasoftware.com>
 * 
 * http://generasoftware.com/
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
#ifndef _COLLECTION_H_
#define _COLLECTION_H_

#include <e32base.h>


template <class K, class T>
class RCollection
{

	struct Item
	{
		K key;
		T value;
	};
public:
    RCollection();
	~RCollection();
public:

	void	AppendL(K key, T value);
	TInt	Find(K key);
	T		Get(K key);
	T		GetByIndex(TInt index);
	K		GetKeyByIndex(TInt index);
	void	RemoveByIndex(TInt index);
	void	Remove(K key);
    void    Remove(T value);
	TInt	Count();
private:


private:
	RPointerArray<Item> iCollection;
};

//////////////////////////////////////////////////////////////////////////
template<class K, class T>
RCollection<K, T>::RCollection()
{
	
}

//////////////////////////////////////////////////////////////////////////
template<class K, class T>
void RCollection<K, T>::AppendL(K key, T value)
{
	for (TInt i = 0; i < iCollection.Count(); ++i)
	{
		if (key == iCollection[i]->key)
		{
			RemoveByIndex(i);
			break;
		}
	}

	Item* it = new (ELeave) Item;
	it->key = key;
	it->value = value;
    User::LeaveIfError(iCollection.Append(it));
}

//////////////////////////////////////////////////////////////////////////
template<class K, class T>
TInt RCollection<K, T>::Find(K key)
{
	for (TInt i = 0; i < iCollection.Count(); ++i)
	{
		if (key == iCollection[i]->key)
		{
			return i;
		}
	}

	return KErrNotFound;
}

//////////////////////////////////////////////////////////////////////////
template<class K, class T>
T RCollection<K, T>::Get(K key)
{
	return GetByIndex( Find( key ) );
}

//////////////////////////////////////////////////////////////////////////
template<class K, class T>
T RCollection<K, T>::GetByIndex(TInt index)
{
	__ASSERT_ALWAYS(index < iCollection.Count(), User::Panic(_L("<CColection>"), KErrOverflow));
    __ASSERT_ALWAYS(index >= 0, User::Panic(_L("<CColection>"), KErrUnderflow));

	return iCollection[index]->value;
}

//////////////////////////////////////////////////////////////////////////
template<class K, class T>
K RCollection<K, T>::GetKeyByIndex(TInt index)
{
    __ASSERT_ALWAYS(index < iCollection.Count(), User::Panic(_L("<CColection>"), KErrOverflow));
    __ASSERT_ALWAYS(index >= 0, User::Panic(_L("<CColection>"), KErrUnderflow));
	return iCollection[index]->key;
}

template<class K, class T>
void RCollection<K, T>::RemoveByIndex(TInt index)
{
	if (index < iCollection.Count())
	{
		delete iCollection[index];
		iCollection.Remove(index);
	}
	
}

template<class K, class T>
void RCollection<K, T>::Remove(K key)
{
	for (TInt i = 0; i < iCollection.Count(); ++i)
	{
		if (key == iCollection[i]->key)
		{
			RemoveByIndex(i);
		}
	}
}

template<class K, class T>
void RCollection<K, T>::Remove(T value)
{
    for (TInt i = 0; i < iCollection.Count(); ++i)
    {
        if (value == iCollection[i]->value)
        {
            RemoveByIndex(i);
        }
    }
}

template<class K, class T>
RCollection<K, T>::~RCollection()
{
    iCollection.ResetAndDestroy();
}

template<class K, class T>
TInt RCollection<K, T>::Count()
{
	return iCollection.Count();
}
#endif // _COLLECTION_H_

